package com.nowcoder.topic.sort.middle;

import java.util.Arrays;

/**
 * NC212 颜色分类
 * @author d3y1
 */
public class NC212{
    private final int KIND = 3;

    private interface Color{
        int RED = 0;
        int WHITE = 1;
        int BLUE = 2;
    }

    /**
     * 代码中的类名、方法名、参数名已经指定，请勿修改，直接返回方法规定的值即可
     *
     *
     * @param colors int整型一维数组
     * @return int整型一维数组
     */
    public int[] sortColor (int[] colors) {
        // return solution1(colors);
        // return solution2(colors);
        // return solution3(colors);
        return solution4(colors);
    }

    /**
     * 统计
     * @param colors
     * @return
     */
    private int[] solution1(int[] colors){
        int n = colors.length;

        int[] cnt = new int[KIND];
        for(int color: colors){
            cnt[color]++;
        }

        // int[] result = new int[n];

        // int i = 0;
        // for(int j=1; j<=cnt[Color.RED]; j++){
        //     result[i++] = Color.RED;
        // }
        // for(int j=1; j<=cnt[Color.WHITE]; j++){
        //     result[i++] = Color.WHITE;
        // }
        // for(int j=1; j<=cnt[Color.BLUE]; j++){
        //     result[i++] = Color.BLUE;
        // }

        // for(int color=Color.RED; color<=Color.BLUE; color++){
        //     for(int j=1; j<=cnt[color]; j++){
        //         colors[i++] = color;
        //     }
        // }

        for(int i=0; i<n; i++){
            if(i < cnt[Color.RED]){
                colors[i] = Color.RED;
            }else if(cnt[Color.RED]<=i && i<cnt[Color.RED]+cnt[Color.WHITE]){
                colors[i] = Color.WHITE;
            }else{
                colors[i] = Color.BLUE;
            }
        }

        return colors;
    }

    /**
     * 数组排序
     * @param colors
     * @return
     */
    private int[] solution2(int[] colors){
        Arrays.sort(colors);

        return colors;
    }

    /**
     * 三指针
     * @param colors
     * @return
     */
    private int[] solution3(int[] colors){
        int n = colors.length;

        int left = 0;
        int right = n-1;
        for(int i=0; i<=right; i++){
            // 2 -> 右边
            // (2...2) -> (2...2)
            // (2...1) -> (1...2)
            // (2...0) -> (0...2)
            while(i<=right && colors[i]==Color.BLUE){
                swap(colors, i, right--);
            }

            // 左边 <- 0
            // (0) <- (0)
            // (0...1) <- (1...0)
            if(colors[i] == Color.RED){
                swap(colors, i, left++);
            }
        }

        return colors;
    }

    /**
     * 三指针: 简化
     * @param colors
     * @return
     */
    private int[] solution4(int[] colors){
        int n = colors.length;

        int left = 0;
        int right = n-1;
        int i = 0;
        while(i <= right){
            // 2 -> 右边
            // (2...2) -> (2...2)
            // (2...1) -> (1...2)
            // (2...0) -> (0...2)
            if(colors[i] == Color.BLUE){
                swap(colors, i, right--);
            }
            // 左边 <- 0
            // (0) <- (0)
            // (0...1) <- (1...0)
            else if(colors[i] == Color.RED){
                swap(colors, i++, left++);
            }
            else{
                i++;
            }
        }

        return colors;
    }

    /**
     * 交换
     * @param colors
     * @param m
     * @param n
     */
    private void swap(int[] colors, int m, int n){
        int tmp = colors[m];
        colors[m] = colors[n];
        colors[n] = tmp;
    }
}